package com.kb.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.system.api.category.CategoryApi;
import cn.iocoder.yudao.module.system.api.category.CategoryControllerApi;
import cn.iocoder.yudao.module.system.api.category.vo.CategoryCreateReqVO;
import cn.iocoder.yudao.module.system.api.organization.OrganizationApi;
import cn.iocoder.yudao.module.system.api.organization.dto.OrganizationCreateReqDTO;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.util.StringUtil;
import com.kb.common.MeException;
import com.kb.dto.ComponentSyncDTO;
import com.kb.entity.*;
import com.kb.enums.BizCode;
import com.kb.mapper.mysql.*;
import com.kb.service.*;
import com.kb.service.gc.AggregationFieldService;
import com.kb.service.gc.ComponentEsService;
import com.kb.util.GCutil;
import com.kb.util.MessageUtil;
import com.xxl.job.core.context.XxlJobHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.CollectionUtils;
import resource.file.server.api.FileApi;
import resource.file.server.api.dto.FileCreateReqDTO;
import resource.file.server.api.dto.FileCreateRespDTO;

import javax.annotation.Resource;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@DS("master")
@Service
@RefreshScope
@Slf4j
public class CallbackNotificationServiceImpl extends ServiceImpl<CallbackNotificationDao, CallbackNotification> implements CallbackNotificationService {
    @Resource
    private CallbackNotificationDao callbackNotificationDao;
    @Resource
    private ComponentModelFPService componentModelFPService;
    @Resource
    private ComponentModelSbService componentModelSbService;
    @Resource
    private ComponentModel3dService componentModel3dService;
    @Resource
    private HeaderDao headerDao;
    @Resource
    private HeaderService headerService;
    @Resource
    private ComponentDataService componentDataService;
    @Resource
    private ComponentDao componentDao;
    @Resource
    private DataHeaderFieldService dataHeaderFieldService;
    @Resource
    private ComponentDataHeaderFieldDao componentDataHeaderFieldDao;
    @Resource
    private ModelApplicationDao modelApplicationDao;
    @Resource
    private ComponentEsService componentEsService;
    @Autowired
    private DataSourceTransactionManager dstManager;
    @Resource
    private AggregationFieldService aggregationFieldService;

    @Value("${gc.clientId}")
    private String clientId;

    @Value("${gc.gcUrl}")
    private String gcUrl;
    @Value("${gc.connectionTimeout:6000}")
    private int connectionTimeout;
    @Value("${idType.footprint}")
    private String footprint;
    @Value("${idType.symbol}")
    private String symbol;
    @Value("${idType.3d}")
    private String mode3dId;

    // 文件rpc接口
    @Resource
    private FileApi fileApi;

    // 分类rpc接口
    @Resource
    private CategoryControllerApi categoryControllerApi;

    // 组织(厂商)rpc接口
    @Resource
    private OrganizationApi organizationApi;
    @Resource
    private CategoryApi categoryApi;


    @Override
    @DSTransactional
    public void callbackNotification(List<CallbackNotification> callbackNotificationList) throws MeException {
        List<CallbackNotification> list = new ArrayList<>();
        for (CallbackNotification callbackNotification : callbackNotificationList) {
            callbackNotification.setResourceId(callbackNotification.getResourceId());
            callbackNotification.setPartNumber(callbackNotification.getPartNumber());
            callbackNotification.setCreateTime(LocalDateTime.now());
            callbackNotification.setCreateBy("gc");
            list.add(callbackNotification);
        }
        try {
            this.saveBatch(list);
        } catch (Exception e) {
            throw new MeException(e.getMessage());
        }
    }

    @Override
//    @DSTransactional
    public void batchGet(String ids,String dateSource) throws MeException {
        // 定义请求参数
        String url = gcUrl + "/resource/openapi/v1/component/private/batchGet";
        //定义参数
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("idList", ids);
        // 添加自定义头部参数
        String authorizationToken = GCutil.getToken();
        Map<String, String> headers = new HashMap<>();
        headers.put("client-id", clientId);
        headers.put("Authorization", authorizationToken);
        try {

            // 发送带有自定义头部参数的 GET 请求并获取响应
            // 发送 GET 请求
            HttpResponse response = HttpRequest.get(url)
                    .form(paramMap)
                    .addHeaders(headers)
                    .execute();

//            System.out.println(response.body());
            if (!Objects.equals(response.getStatus(), HttpStatus.HTTP_OK)) {
                throw new MeException("请求异常：" + response.body());
            }
//            String body = "{\"code\":0,\"data\":[{\"component\":{\"id\":\"41021041670200832\",\"partNumber\":\"ABC-050605\",\"orgId\":0,\"datasheetName\":\"\",\"datasheet\":\"https://www.yageo.com/upload/media/product/productsearch/datasheet/rchip/PYu-AC_51_RoHS_L_10.pdf\",\"datasheetFileId\":\"178148892053999616\",\"seriesNumber\":null,\"categoryId\":null,\"version\":1,\"symbolId\":\"40916487385486336\",\"footprintId\":\"40916487469372416\",\"model3dId\":\"40916487544869888\",\"componentImages\":null,\"techTemplateFields\":\"{\\\"key0\\\": \\\"ABC-050605\\\", \\\"key1\\\": \\\"国创\\\", \\\"key2\\\": \\\"\\\", \\\"key3\\\": \\\"https://www.yageo.com/upload/media/product/productsearch/datasheet/rchip/PYu-AC_51_RoHS_L_10.pdf\\\", \\\"key4\\\": \\\"\\\", \\\"key5\\\": \\\"\\\", \\\"key6\\\": \\\"\\\", \\\"key7\\\": \\\"A&B&C\\\", \\\"key8\\\": \\\"84603.0\\\", \\\"key9\\\": \\\"0.81\\\", \\\"key10\\\": \\\"0.0\\\", \\\"key11\\\": \\\"1.0\\\", \\\"key12\\\": \\\"卷带（TR）,剪切带（CT）,Digi-Reel® 得捷定制卷带\\\", \\\"key13\\\": \\\"AC\\\", \\\"key14\\\": \\\"在售\\\", \\\"key15\\\": \\\"100 Ohms\\\", \\\"key16\\\": \\\"±1%\\\", \\\"key17\\\": \\\"0.05W，1/20W\\\", \\\"key18\\\": \\\"厚膜\\\", \\\"key19\\\": \\\"汽车级 AEC-Q200，防潮\\\", \\\"key20\\\": \\\"±200ppm/°C\\\", \\\"key21\\\": \\\"-55°C ~ 155°C\\\", \\\"key22\\\": \\\"0201（0603 公制）\\\", \\\"key23\\\": \\\"201.0\\\", \\\"key24\\\": \\\"AEC-Q200\\\", \\\"key25\\\": \\\"0.024\\\\\\\" 长 x 0.012\\\\\\\" 宽（0.60mm x 0.30mm）\\\", \\\"key26\\\": \\\"0.010\\\\\\\"（0.26mm）\\\", \\\"key27\\\": \\\"2.0\\\", \\\"key28\\\": \\\"-\\\", \\\"key29\\\": \\\"____________ - 2024-03-17T042346.059.csv\\\"}\",\"otherFields\":\"{}\",\"similarityFields\":\"{\\\"key17\\\": \\\"0.05，20\\\", \\\"key21\\\": \\\"-55~155\\\", \\\"key25\\\": \\\"0.024x0.012(0.6x0.3)\\\", \\\"key26\\\": \\\"0.01(0.26)\\\"}\",\"priceStockId\":null,\"setId\":\"41021041057832448\",\"description\":\"A&B&C\",\"status\":2},\"header\":{\"id\":\"41021041057832448\",\"type\":2,\"tableLabel\":null,\"orgCategoryId\":\"175290536150831104\",\"platformCategoryId\":\"175290536150831104\",\"status\":2},\"fields\":[{\"id\":\"41021041133329920\",\"setId\":\"41021041057832448\",\"fieldName\":\"*产品型号\",\"fieldKey\":\"key0\",\"fieldGroupName\":null,\"position\":\"A\"},{\"id\":\"41021041141718528\",\"setId\":\"41021041057832448\",\"fieldName\":\"*厂商\",\"fieldKey\":\"key1\",\"fieldGroupName\":null,\"position\":\"B\"},{\"id\":\"41021041141718529\",\"setId\":\"41021041057832448\",\"fieldName\":\"产品手册名称\",\"fieldKey\":\"key2\",\"fieldGroupName\":null,\"position\":\"C\"},{\"id\":\"41021041141718530\",\"setId\":\"41021041057832448\",\"fieldName\":\"原厂链接\",\"fieldKey\":\"key3\",\"fieldGroupName\":null,\"position\":\"D\"},{\"id\":\"41021041141718531\",\"setId\":\"41021041057832448\",\"fieldName\":\"标准符号名\",\"fieldKey\":\"key4\",\"fieldGroupName\":null,\"position\":\"E\"},{\"id\":\"41021041141718532\",\"setId\":\"41021041057832448\",\"fieldName\":\"标准封装名\",\"fieldKey\":\"key5\",\"fieldGroupName\":null,\"position\":\"F\"},{\"id\":\"41021041141718533\",\"setId\":\"41021041057832448\",\"fieldName\":\"标准3DModel名\",\"fieldKey\":\"key6\",\"fieldGroupName\":null,\"position\":\"G\"},{\"id\":\"41021041141718534\",\"setId\":\"41021041057832448\",\"fieldName\":\"描述\",\"fieldKey\":\"key7\",\"fieldGroupName\":null,\"position\":\"H\"},{\"id\":\"41021041141718535\",\"setId\":\"41021041057832448\",\"fieldName\":\"库存\",\"fieldKey\":\"key8\",\"fieldGroupName\":null,\"position\":\"I\"},{\"id\":\"41021041141718536\",\"setId\":\"41021041057832448\",\"fieldName\":\"价格\",\"fieldKey\":\"key9\",\"fieldGroupName\":null,\"position\":\"J\"},{\"id\":\"41021041141718537\",\"setId\":\"41021041057832448\",\"fieldName\":\"@ qty\",\"fieldKey\":\"key10\",\"fieldGroupName\":null,\"position\":\"K\"},{\"id\":\"41021041141718538\",\"setId\":\"41021041057832448\",\"fieldName\":\"最小数量\",\"fieldKey\":\"key11\",\"fieldGroupName\":null,\"position\":\"L\"},{\"id\":\"41021041141718539\",\"setId\":\"41021041057832448\",\"fieldName\":\" 包装\",\"fieldKey\":\"key12\",\"fieldGroupName\":null,\"position\":\"M\"},{\"id\":\"41021041141718540\",\"setId\":\"41021041057832448\",\"fieldName\":\"系列\",\"fieldKey\":\"key13\",\"fieldGroupName\":null,\"position\":\"N\"},{\"id\":\"41021041141718541\",\"setId\":\"41021041057832448\",\"fieldName\":\"产品状态\",\"fieldKey\":\"key14\",\"fieldGroupName\":null,\"position\":\"O\"},{\"id\":\"41021041141718542\",\"setId\":\"41021041057832448\",\"fieldName\":\"电阻\",\"fieldKey\":\"key15\",\"fieldGroupName\":null,\"position\":\"P\"},{\"id\":\"41021041141718543\",\"setId\":\"41021041057832448\",\"fieldName\":\"容差\",\"fieldKey\":\"key16\",\"fieldGroupName\":null,\"position\":\"Q\"},{\"id\":\"41021041141718544\",\"setId\":\"41021041057832448\",\"fieldName\":\"功率 (W)\",\"fieldKey\":\"key17\",\"fieldGroupName\":null,\"position\":\"R\"},{\"id\":\"41021041141718545\",\"setId\":\"41021041057832448\",\"fieldName\":\"成分\",\"fieldKey\":\"key18\",\"fieldGroupName\":null,\"position\":\"S\"},{\"id\":\"41021041141718546\",\"setId\":\"41021041057832448\",\"fieldName\":\"特性\",\"fieldKey\":\"key19\",\"fieldGroupName\":null,\"position\":\"T\"},{\"id\":\"41021041141718547\",\"setId\":\"41021041057832448\",\"fieldName\":\"温度系数\",\"fieldKey\":\"key20\",\"fieldGroupName\":null,\"position\":\"U\"},{\"id\":\"41021041141718548\",\"setId\":\"41021041057832448\",\"fieldName\":\"工作温度\",\"fieldKey\":\"key21\",\"fieldGroupName\":null,\"position\":\"V\"},{\"id\":\"41021041141718549\",\"setId\":\"41021041057832448\",\"fieldName\":\"封装/外壳\",\"fieldKey\":\"key22\",\"fieldGroupName\":null,\"position\":\"W\"},{\"id\":\"41021041141718550\",\"setId\":\"41021041057832448\",\"fieldName\":\"供应商器件封装\",\"fieldKey\":\"key23\",\"fieldGroupName\":null,\"position\":\"X\"},{\"id\":\"41021041141718551\",\"setId\":\"41021041057832448\",\"fieldName\":\"等级\",\"fieldKey\":\"key24\",\"fieldGroupName\":null,\"position\":\"Y\"},{\"id\":\"41021041141718552\",\"setId\":\"41021041057832448\",\"fieldName\":\"大小 / 尺寸\",\"fieldKey\":\"key25\",\"fieldGroupName\":null,\"position\":\"Z\"},{\"id\":\"41021041141718553\",\"setId\":\"41021041057832448\",\"fieldName\":\"高度 - 安装（最大值）\",\"fieldKey\":\"key26\",\"fieldGroupName\":null,\"position\":\"AA\"},{\"id\":\"41021041141718554\",\"setId\":\"41021041057832448\",\"fieldName\":\"端子数\",\"fieldKey\":\"key27\",\"fieldGroupName\":null,\"position\":\"AB\"},{\"id\":\"41021041141718555\",\"setId\":\"41021041057832448\",\"fieldName\":\"故障率\",\"fieldKey\":\"key28\",\"fieldGroupName\":null,\"position\":\"AC\"},{\"id\":\"41021041141718556\",\"setId\":\"41021041057832448\",\"fieldName\":\"Original_File_Name\",\"fieldKey\":\"key29\",\"fieldGroupName\":null,\"position\":\"AD\"}],\"symbol\":{\"id\":\"40916487385486336\",\"standardSymbolName\":\"标准符号0506\",\"altiumSymbol\":\"42461676445378560\",\"padsSymbol\":\"44486955263091712\",\"cadenceSymbol\":\"178150999062614016\",\"kicadSymbol\":\"178150999062614016\",\"orgId\":0},\"footprint\":{\"id\":\"40916487469372416\",\"standardFootprintName\":\"标准封装0506\",\"altiumFootprint\":\"42461679003904000\",\"padsFootprint\":\"44486956244558848\",\"cadenceFootprint\":\"178149305880809472\",\"kicadFootprint\":\"178149305880809472\",\"orgId\":0},\"model3D\":{\"id\":\"40916487544869888\",\"standard3dName\":\"标准3D模型0506\",\"step\":\"178149306258296832\",\"orgId\":0}}],\"msg\":\"\"}";

            JSONObject jsonObject = JSONObject.parseObject(response.body());
            JSONArray dataArray = jsonObject.getJSONArray("data");
            if (CollectionUtils.isEmpty(dataArray)) {
                log.info("数据为空");
                XxlJobHelper.log("数据为空");
                throw new MeException("请求异常：" + response.body());
            }
            ObjectMapper mapper = new ObjectMapper();
            List<Long> modeFp = new ArrayList<>();
            List<Long> modeSb = new ArrayList<>();
            List<Long> mode3d = new ArrayList<>();

            //es缓存数据封装
            ComponentSyncDTO componentSync = new ComponentSyncDTO();
            List<ComponentData> esComponentDataList = new ArrayList<>();
            List<ComponentModelSb> componentModelSbList = new ArrayList<>();
            List<ComponentModelFP> componentModelFpList = new ArrayList<>();
            List<ComponentModel3d> componentModel3dList = new ArrayList<>();
            List<Header> componentDataHeaderList = new ArrayList<>();

            List<ComponentData> componentDataList = new ArrayList<>();

            List<ComponentDataHeaderField> fields = Collections.emptyList();
            List<ComponentDataHeaderField> fieldList = Collections.emptyList();
            for (int i = 0; i < dataArray.size(); i++) {
                JSONObject json = dataArray.getJSONObject(i);
                ComponentData componentData = mapper.readValue(json.getString("component"), ComponentData.class);
                Header header = mapper.readValue(json.getString("header"), Header.class);
                JSONArray fieldsArray = json.getJSONArray("fields");
                fieldList = JSONArray.parseArray(fieldsArray.toJSONString(), ComponentDataHeaderField.class);
                ComponentModelSb componentModelSb = mapper.readValue(json.getString("symbol"), ComponentModelSb.class);
                ComponentModelFP componentModelFP = mapper.readValue(json.getString("footprint"), ComponentModelFP.class);
                ComponentModel3d componentModel3d = mapper.readValue(json.getString("model3D"), ComponentModel3d.class);

                componentSync.setTaskType(1);
                if (!Objects.equals(componentData.getId(), componentData.getOriginalId())) {
                    componentDao.delByOriginalId(componentData.getOriginalId());
                    componentSync.setTaskType(2);
                    componentData.setUpdateTime(LocalDateTime.now());
                } else {
                    componentData.setCreateTime(LocalDateTime.now());
                    componentData.setUpdateTime(LocalDateTime.now());
                }
                if (Objects.nonNull(dateSource)) {
                    componentData.setDataSource(dateSource);
                }
                componentDataService.saveOrUpdate(componentData);
//                componentDao.insert(componentData);
                componentModelFPService.saveOrUpdate(componentModelFP);
                componentModelSbService.saveOrUpdate(componentModelSb);
                componentModel3dService.saveOrUpdate(componentModel3d);
                //需要先判断是否set_id存在，不存在再插入
                LambdaQueryWrapper<ComponentDataHeaderField> queryWrapper = Wrappers.lambdaQuery();
                queryWrapper.eq(ComponentDataHeaderField::getSetId, componentData.getSetId());
                fields = componentDataHeaderFieldDao.selectList(queryWrapper);
                if (CollectionUtils.isEmpty(fields)) {
                    dataHeaderFieldService.saveOrUpdateBatch(fieldList);
                }
                LambdaQueryWrapper<Header> query = Wrappers.lambdaQuery();
                query.eq(Header::getId, componentData.getSetId());
                List<Header> headerList = headerDao.selectList(query);
                if (CollectionUtils.isEmpty(headerList)) {
                    headerService.saveOrUpdate(header);
                }
                componentDataList.add(componentData);
                //es数据封装
                esComponentDataList.add(componentData);
                componentDataHeaderList.add(header);
                componentModelSbList.add(componentModelSb);
                componentModel3dList.add(componentModel3d);
                componentModelFpList.add(componentModelFP);
//                componentDataHeaderFieldList.add(fieldList);
                componentSync.setComponentDataList(esComponentDataList);
                componentSync.setComponentDataHeaderList(componentDataHeaderList);
                componentSync.setComponentModelSbList(componentModelSbList);
                componentSync.setComponentModelFpList(componentModelFpList);
                componentSync.setComponentModel3dList(componentModel3dList);
                componentSync.setComponentDataHeaderFieldList(fieldList);
//                componentSync.setTaskType(1);

                //文件下载
                String[] fpList = footprint.split(",");
                for (String s : fpList) {
                    if (Objects.equals(s, "altiumFootprint")) {
                        modeFp.add(componentModelFP.getAltiumFootprint());
                    } else if (Objects.equals(s, "kicadFootprint")) {
                        modeFp.add(componentModelFP.getKicadFootprint());
                    } else if (Objects.equals(s, "cadenceFootprint")) {
                        modeFp.add(componentModelFP.getCadenceFootprint());
                    } else if (Objects.equals(s, "footprintImage")) {
                        modeFp.add(componentModelFP.getFootprintImage());
                    } else if (Objects.equals(s, "vxinFootprint")) {
                        modeFp.add(componentModelFP.getVxinFootprint());
                    } else if (Objects.equals(s, "padsFootprint")) {
                        modeFp.add(componentModelFP.getPadsFootprint());
                    }
                }
                //3d
                String[] mode3dIdList = mode3dId.split(",");
                for (String s : mode3dIdList) {
                    if (Objects.equals(s, "image3d")) {
                        mode3d.add(componentModel3d.getImage3d());
                    } else if (Objects.equals(s, "auto3dModelDfmReport")) {
                        mode3d.add(componentModel3d.getAuto3dModelDfmReport());
                    } else if (Objects.equals(s, "manual3dModelDfmReport")) {
                        mode3d.add(componentModel3d.getManual3dModelDfmReport());
                    } else if (Objects.equals(s, "step")) {
                        mode3d.add(componentModel3d.getStep());
                    } else if (Objects.equals(s, "vxinModel3d")) {
                        mode3d.add(componentModel3d.getVxinModel3d());
                    }
                }
                //sb
                String[] symbolList = symbol.split(",");
                for (String s : symbolList) {
                    if (Objects.equals(s, "altiumSymbol")) {
                        modeSb.add(componentModelSb.getAltiumSymbol());
                    } else if (Objects.equals(s, "padsSymbol")) {
                        modeSb.add(componentModelSb.getPadsSymbol());
                    } else if (Objects.equals(s, "cadenceSymbol")) {
                        modeSb.add(componentModelSb.getCadenceSymbol());
                    } else if (Objects.equals(s, "kicadSymbol")) {
                        modeSb.add(componentModelSb.getKicadSymbol());
                    } else if (Objects.equals(s, "vxinSymbol")) {
                        modeSb.add(componentModelSb.getVxinSymbol());
                    } else if (Objects.equals(s, "padsFootprint")) {
                        modeSb.add(componentModelFP.getPadsFootprint());
                    }
                }
                //如果是建模请求数据 消息提醒
                this.notice(componentData.getPartNumber());
            }
            //写缓存到es
            componentEsService.saveComponentIndexData(componentSync);
            //写查询条件
            aggregationFieldService.handleAggregationField(esComponentDataList, componentDataHeaderList, fieldList);
            //产品手册DataSheet文件下载
            if (CollectionUtil.isNotEmpty(componentDataList)) {
                for (ComponentData componentData : componentDataList) {
                    if (!Objects.isNull(componentData) && !Objects.isNull(componentData.getDatasheetFileId())) {
                        this.getFileAndSubscribeId(ids,String.valueOf(componentData.getDatasheetFileId()), BizCode.DATA_SHEET.getType());
                    }
                    if (!Objects.isNull(componentData.getComponentImages())) {
                        this.getFileAndSubscribeId(ids,componentData.getComponentImages(), BizCode.IMAGE.getType());
                    }
                }
            }
            // 3d模型ModelFiles文件下载
            if (CollectionUtil.isNotEmpty(mode3d)) {
                for (Long l : mode3d) {
                    if (l != null) {
                        this.getFileAndSubscribeId(ids,l.toString(), BizCode.MODEL_FILE.getType());
                    }
                }
            }
            //元器件文件下载
            if (CollectionUtil.isNotEmpty(modeFp)) {
                for (Long l : modeFp) {
                    if (l != null) {
                        this.getFileAndSubscribeId(ids,l.toString(), BizCode.FOOT_PRINT.getType());
                    }
                }
            }
            //元器件符号模型下载
            if (CollectionUtil.isNotEmpty(modeSb)) {
                for (Long l : modeSb) {
                    if (l != null) {
                        this.getFileAndSubscribeId(ids,l.toString(), BizCode.SYMBOLS.getType());
                    }
                }
            }
        } catch (Exception e) {
            throw new MeException(e.getMessage());
        }

    }


    /**
     * 异步 提升接口响应速度
     *
     * @param dataArray
     */
    @Async
    public void extracted(JSONArray dataArray) {
        try {
            ObjectMapper mapper = new ObjectMapper();

            List<Long> modeFp = new ArrayList<>();
            List<Long> modeSb = new ArrayList<>();
            List<Long> mode3d = new ArrayList<>();
            List<ComponentData> componentDataList = new ArrayList<>();
            //es缓存数据封装
            ComponentSyncDTO componentSync = new ComponentSyncDTO();
            List<ComponentData> esComponentDataList = new ArrayList<>();
            List<ComponentModelSb> componentModelSbList = new ArrayList<>();
            List<ComponentModelFP> componentModelFpList = new ArrayList<>();
            List<ComponentModel3d> componentModel3dList = new ArrayList<>();
            List<Header> componentDataHeaderList = new ArrayList<>();
//            List<ComponentDataHeaderField> componentDataHeaderFieldList = new ArrayList<>();

            List<ComponentDataHeaderField> fields = Collections.emptyList();
            List<ComponentDataHeaderField> fieldList = Collections.emptyList();
            for (int i = 0; i < dataArray.size(); i++) {
                JSONObject json = dataArray.getJSONObject(i);
                ComponentData componentData = mapper.readValue(json.getString("component"), ComponentData.class);
                Header header = mapper.readValue(json.getString("header"), Header.class);
                JSONArray fieldsArray = json.getJSONArray("fields");
                fieldList = JSONArray.parseArray(fieldsArray.toJSONString(), ComponentDataHeaderField.class);
                ComponentModelSb componentModelSb = null;
                if (json.get("symbol") != null) {
                    componentModelSb = mapper.readValue(json.getString("symbol"), ComponentModelSb.class);
                }
                ComponentModelFP componentModelFP = mapper.readValue(json.getString("footprint"), ComponentModelFP.class);
                ComponentModel3d componentModel3d = mapper.readValue(json.getString("model3D"), ComponentModel3d.class);
                //更新场景 当id和originalId不相等即为更新，删除旧的 插入新的
                componentSync.setTaskType(1);
                if (!Objects.equals(componentData.getId(), componentData.getOriginalId())) {
                    componentDao.delByOriginalId(componentData.getOriginalId());
                    componentSync.setTaskType(2);
                    componentData.setUpdateTime(LocalDateTime.now());
                } else {
                    componentData.setCreateTime(LocalDateTime.now());
                    componentData.setUpdateTime(LocalDateTime.now());
                }

                componentDataService.saveOrUpdate(componentData);
                componentModelFPService.saveOrUpdate(componentModelFP);
                if (Objects.nonNull(componentModelSb)) {
                    componentModelSbService.saveOrUpdate(componentModelSb);
                }
                componentModel3dService.saveOrUpdate(componentModel3d);
                //需要先判断是否set_id存在，不存在再插入
                LambdaQueryWrapper<ComponentDataHeaderField> queryWrapper = Wrappers.lambdaQuery();
                queryWrapper.eq(ComponentDataHeaderField::getSetId, componentData.getSetId());
                fields = componentDataHeaderFieldDao.selectList(queryWrapper);
                if (CollectionUtils.isEmpty(fields)) {
                    dataHeaderFieldService.saveOrUpdateBatch(fieldList);
                }
                LambdaQueryWrapper<Header> query = Wrappers.lambdaQuery();
                query.eq(Header::getId, componentData.getSetId());
                List<Header> headerList = headerDao.selectList(query);

                //跟新目录数量
                HashMap<Long, Long> newHashMap = MapUtil.newHashMap();
                newHashMap.put(header.getPlatformCategoryId(), 1L);
                categoryApi.updateCategoryProductCount(newHashMap);
                if (CollectionUtils.isEmpty(headerList)) {
                    headerService.saveOrUpdate(header);
                }
                componentDataList.add(componentData);
                //es数据封装
                esComponentDataList.add(componentData);
                componentDataHeaderList.add(header);
                componentModelSbList.add(componentModelSb);
                componentModel3dList.add(componentModel3d);
                componentModelFpList.add(componentModelFP);
//                componentDataHeaderFieldList.add(fieldList);
                componentSync.setComponentDataList(esComponentDataList);
                componentSync.setComponentDataHeaderList(componentDataHeaderList);
                componentSync.setComponentModelSbList(componentModelSbList);
                componentSync.setComponentModelFpList(componentModelFpList);
                componentSync.setComponentModel3dList(componentModel3dList);
                componentSync.setComponentDataHeaderFieldList(fieldList);


                //文件下载
                String[] fpList = footprint.split(",");
                for (String s : fpList) {
                    if (Objects.equals(s, "altiumFootprint")) {
                        modeFp.add(componentModelFP.getAltiumFootprint());
                    } else if (Objects.equals(s, "kicadFootprint")) {
                        modeFp.add(componentModelFP.getKicadFootprint());
                    } else if (Objects.equals(s, "cadenceFootprint")) {
                        modeFp.add(componentModelFP.getCadenceFootprint());
                    } else if (Objects.equals(s, "footprintImage")) {
                        modeFp.add(componentModelFP.getFootprintImage());
                    } else if (Objects.equals(s, "vxinFootprint")) {
                        modeFp.add(componentModelFP.getVxinFootprint());
                    } else if (Objects.equals(s, "padsFootprint")) {
                        modeFp.add(componentModelFP.getPadsFootprint());
                    }
                }
                //3d
                String[] mode3dIdList = mode3dId.split(",");
                for (String s : mode3dIdList) {
                    if (Objects.equals(s, "image3d")) {
                        mode3d.add(componentModel3d.getImage3d());
                    } else if (Objects.equals(s, "auto3dModelDfmReport")) {
                        mode3d.add(componentModel3d.getAuto3dModelDfmReport());
                    } else if (Objects.equals(s, "manual3dModelDfmReport")) {
                        mode3d.add(componentModel3d.getManual3dModelDfmReport());
                    } else if (Objects.equals(s, "step")) {
                        mode3d.add(componentModel3d.getStep());
                    } else if (Objects.equals(s, "vxinModel3d")) {
                        mode3d.add(componentModel3d.getVxinModel3d());
                    }
                }
                //sb
                String[] symbolList = symbol.split(",");
                for (String s : symbolList) {
                    if (Objects.equals(s, "altiumSymbol")) {
                        modeSb.add(componentModelSb.getAltiumSymbol());
                    } else if (Objects.equals(s, "padsSymbol")) {
                        modeSb.add(componentModelSb.getPadsSymbol());
                    } else if (Objects.equals(s, "cadenceSymbol")) {
                        modeSb.add(componentModelSb.getCadenceSymbol());
                    } else if (Objects.equals(s, "kicadSymbol")) {
                        modeSb.add(componentModelSb.getKicadSymbol());
                    } else if (Objects.equals(s, "vxinSymbol")) {
                        modeSb.add(componentModelSb.getVxinSymbol());
                    } else if (Objects.equals(s, "padsFootprint")) {
                        modeSb.add(componentModelFP.getPadsFootprint());
                    }
                }
                //如果是建模请求数据 消息提醒
//                this.notice(componentData.getPartNumber());
            }

            //写缓存到es
            componentEsService.saveComponentIndexData(componentSync);
            //写查询条件
            aggregationFieldService.handleAggregationField(esComponentDataList, componentDataHeaderList, fieldList);
            //产品手册DataSheet文件下载
            if (CollectionUtil.isNotEmpty(componentDataList)) {
                for (ComponentData componentData : componentDataList) {
                    if (!Objects.isNull(componentData) && !Objects.isNull(componentData.getDatasheetFileId())) {
                        this.getFile(String.valueOf(componentData.getDatasheetFileId()), BizCode.DATA_SHEET.getType());
                    }
                    if (!Objects.isNull(componentData.getComponentImages())) {
                        this.getFile(componentData.getComponentImages(), BizCode.IMAGE.getType());
                    }
                }
            }
            // 3d模型ModelFiles文件下载
            if (CollectionUtil.isNotEmpty(mode3d)) {
                for (Long l : mode3d) {
                    if (l != null) {
                        this.getFile(l.toString(), BizCode.MODEL_FILE.getType());
                    }
                }
            }
            //元器件文件下载
            if (CollectionUtil.isNotEmpty(modeFp)) {
                for (Long l : modeFp) {
                    if (l != null) {
                        this.getFile(l.toString(), BizCode.FOOT_PRINT.getType());
                    }
                }
            }
            //元器件符号模型下载
            if (CollectionUtil.isNotEmpty(modeSb)) {
                for (Long l : modeSb) {
                    if (l != null) {
                        this.getFile(l.toString(), BizCode.SYMBOLS.getType());
                    }
                }
            }
        } catch (Exception e) {
            log.info("文件更新/拉取失败");
            throw new RuntimeException(e);
        }
    }


    /**
     * 建模请求消息回调
     *
     * @param number
     */
    public void notice(String number) {
        LambdaQueryWrapper<ModelApplication> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ModelApplication::getPartNumber, number).last("limit 1");
        //判断此次数据拉取 是否是我们发起的建模请求
        ModelApplication modelApplication = modelApplicationDao.selectOne(wrapper);
        if (Objects.nonNull(modelApplication)) {
            //todo 直接通知到系统 需要对应系统提供接口或者数据库 2个方案 我通知收到建模 或者直接把建模信息写到对应数据库,
            // 但是我作为数据中台,写数据不应该我做,我需要面对很多应用,我制定规则,应用端统一使用我的方式拿数据,故用前者,提供接口,统一参数 id/型号,flag,post请求,
            // 回调成功把状态写回kb_model_application表的is_notice字段
            MessageUtil.sentMessage(modelApplication.getCreateBy(), "您好，您申请的元器件建模（型号：" + modelApplication.getPartNumber() + "）已完成，请登录查看", "国创资源库");
        }
    }

    @Override
    public void getFile(String id,String type) throws MeException {
        if (id == null) {
            log.info("文件id为空，不需要同步");
            XxlJobHelper.log("文件id为空，不需要同步");
            return;
        }
        if (fileApi.getFileById(Long.parseLong(id)).isSuccess()) {
            log.info("文件已经同步过了,不需要重新同步{}", id);
            return;
        }
        String fileURL = gcUrl + "/resource/openapi/v1/component/private/get?id=" + id;

        FileCreateReqDTO fileCreateReqDTO = new FileCreateReqDTO();
        try {
            String authorizationToken = GCutil.getToken();
            URL url = new URL(fileURL);
            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setRequestMethod("GET");

            // 设置Authorization头部信息
            httpConn.setRequestProperty("Authorization", authorizationToken);
            httpConn.setRequestProperty("client-id", "resource-jbz-001");
            // 设置连接超时时间为6秒  尝试连接时间 超过这个时间还未连接抛异常
            httpConn.setConnectTimeout(connectionTimeout);
            // 设置读取超时时间为20秒
            httpConn.setReadTimeout(20000);
            int responseCode = httpConn.getResponseCode();
            // 检查 HTTP 响应码
            String fileName = "";
            //        String saveFilePath = "/" + type;
            if (responseCode == HttpURLConnection.HTTP_OK) {
                String disposition = httpConn.getHeaderField("Content-Disposition");

                // 如果 Content-Disposition 存在，则从中提取文件名
                StringBuilder response = new StringBuilder();
                if (disposition != null) {
                    int index = disposition.indexOf("filename=");
                    if (index > 0) {
                        fileName = disposition.substring(index + 9, disposition.length());
                    }
                } else { // 否则从 URL 中获取文件名
                    // 读取响应内容
                    BufferedReader reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
                    // 打印或处理响应数据
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    // 打印或处理响应数据
                    log.info("{}{}", response, id);
                    XxlJobHelper.log("Response Data: " + response + id);
                    MessageUtil.sentMessage("23988", "文件下载失败：Response Data: " + response + id + "type: " + type, "国创资源库");
                    fileName = fileURL.substring(fileURL.lastIndexOf("?") + 1);
                    //下载失败不阻断
//                    reader.close();
//                    throw new MeException(response.toString());
                }
                // 构建保存文件的路径
//                saveFilePath = saveDir + File.separator + fileName;

                // 打开网络输入流
                InputStream inputStream = httpConn.getInputStream();

                // 创建文件输出流
                //          FileOutputStream outputStream = new FileOutputStream(saveFilePath);

                // 读取数据到文件 保存到本地
//                int bytesRead;
//                byte[] buffer = new byte[4096];
//                while ((bytesRead = inputStream.read(buffer)) != -1) {
//                    outputStream.write(buffer, 0, bytesRead);
//                }

                byte[] bytes = IoUtil.readBytes(inputStream);
                //塞入文件数据流
                fileCreateReqDTO.setContent(bytes);
                // 关闭流
                inputStream.close();
                //          outputStream.close();

                log.info("文件 {} 下载完成", fileName);
            } else {
                log.info("无法下载文件，服务器响应码: {}", responseCode);
            }
            httpConn.disconnect();

            //文件所属大类别，1零部件，2元器件,3其他
            fileCreateReqDTO.setType(2);
            // 文件名", example = "yudaoyuanma.png"
            fileCreateReqDTO.setFileName(fileName);
            // 文件路径 ,可以自己规划
//            fileCreateReqDTO.setPath("/resource");
            // 1：3d模型ModelFiles，2：图片Images，3：2D标注图2DAnnotationFiles，4：产品手册DataSheet，5：符号文件Symbols，6：封装FootPrint，0：其他other
            // 按需填写
            fileCreateReqDTO.setBizCode(type);
            // 文件ID与国创保持一致，方便后续维护
            fileCreateReqDTO.setId(Long.parseLong(id));

            CommonResult<FileCreateRespDTO> file = fileApi.createFile(fileCreateReqDTO);

            if (file != null && file.getCheckedData() != null) {
                log.info("文件 {} 保存完成{}", id, file.getCheckedData().getId());
            } else {
                log.error("文件 {} 保存失败{}", id, file);
            }

        } catch (IOException e) {
            MessageUtil.sentMessage("23988", "Response Data: " + e, "国创资源库");
            throw new MeException(e.getMessage());
        }
    }

    @Override
    public void getFileAndSubscribeId(String subscribeId, String id, String type) throws MeException {
        if (id == null) {
            log.info("文件id为空，不需要同步");
            XxlJobHelper.log("文件id为空，不需要同步");
            return;
        }
        if (fileApi.getFileById(Long.parseLong(id)).isSuccess()) {
            log.info("文件已经同步过了,不需要重新同步{}", id);
            return;
        }
        String fileURL;
        fileURL = gcUrl + "/resource/openapi/v1/component/private/get?id=" + id;
        if (Objects.nonNull(subscribeId)) {
            fileURL = gcUrl + "/resource/openapi/v1/component/private/get?subscribeId=" + subscribeId + "&id=" + id;
        }

        FileCreateReqDTO fileCreateReqDTO = new FileCreateReqDTO();
        try {
            String authorizationToken = GCutil.getToken();
            URL url = new URL(fileURL);
            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setRequestMethod("GET");

            // 设置Authorization头部信息
            httpConn.setRequestProperty("Authorization", authorizationToken);
            httpConn.setRequestProperty("client-id", "resource-jbz-001");
            httpConn.setRequestProperty("User-Agent", "Mozilla/5.0"); // 添加User-Agent
            // 设置连接超时时间为6秒  尝试连接时间 超过这个时间还未连接抛异常
            httpConn.setConnectTimeout(connectionTimeout);
            // 设置读取超时时间为20秒
            httpConn.setReadTimeout(20000);
            int responseCode = httpConn.getResponseCode();
            // 检查 HTTP 响应码
            String fileName = "";
            //        String saveFilePath = "/" + type;
            if (responseCode == HttpURLConnection.HTTP_OK) {
                String disposition = httpConn.getHeaderField("Content-Disposition");

                // 如果 Content-Disposition 存在，则从中提取文件名
                StringBuilder response = new StringBuilder();
                if (disposition != null) {
                    int index = disposition.indexOf("filename=");
                    if (index > 0) {
                        fileName = disposition.substring(index + 9, disposition.length());
                    }
                } else { // 否则从 URL 中获取文件名
                    // 读取响应内容
                    BufferedReader reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
                    // 打印或处理响应数据
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    // 打印或处理响应数据
                    log.info("{}{}", response, id);
                    XxlJobHelper.log("Response Data: " + response + id);
//                    MessageUtil.sentMessage("23988", "文件下载失败：Response Data: " + response + id + "type: " + type, "国创资源库");
                    fileName = fileURL.substring(fileURL.lastIndexOf("?") + 1);
                }
                //解析返回数据
                JSONObject jsonObject = JSONObject.parseObject(response.toString());
                if (jsonObject != null && !jsonObject.isEmpty()) {
                    JSONArray errorsArray = jsonObject.getJSONArray("errors");
                    log.info("无法下载文件，服务器响应码: {}", responseCode);
//                    MessageUtil.sentMessage("23988", "，返回异常: "+JSONUtil.parse(errorsArray),"国创资源库");
                    throw new MeException("无法下载文件，返回异常: "+ JSONUtil.parse(errorsArray));
                }

                // 打开网络输入流
                InputStream inputStream = httpConn.getInputStream();

                byte[] bytes = IoUtil.readBytes(inputStream);
                //塞入文件数据流
                fileCreateReqDTO.setContent(bytes);
                // 关闭流
                inputStream.close();

                log.info("文件 {} 下载完成", fileName);
            } else {
                log.info("无法下载文件，服务器响应码: {}", responseCode);
                MessageUtil.sentMessage("23988", "无法下载文件，服务器响应码: "+responseCode,"国创资源库");
                throw new MeException("无法下载文件，服务器响应码: {}", responseCode);
            }
            httpConn.disconnect();

            //文件所属大类别，1零部件，2元器件,3其他
            fileCreateReqDTO.setType(2);
            // 文件名", example = "yudaoyuanma.png"
            fileCreateReqDTO.setFileName(fileName);
            // 文件路径 ,可以自己规划
//            fileCreateReqDTO.setPath("/resource");
            // 1：3d模型ModelFiles，2：图片Images，3：2D标注图2DAnnotationFiles，4：产品手册DataSheet，5：符号文件Symbols，6：封装FootPrint，0：其他other
            // 按需填写
            fileCreateReqDTO.setBizCode(type);
            // 文件ID与国创保持一致，方便后续维护
            fileCreateReqDTO.setId(Long.parseLong(id));

            CommonResult<FileCreateRespDTO> file = fileApi.createFile(fileCreateReqDTO);
            if (file != null && file.getCheckedData() != null) {
                log.info("文件 {} 保存完成{}", id, file.getCheckedData().getId());
            } else {
                log.error("文件 {} 保存失败{}", id, file);
            }

        } catch (IOException e) {
            MessageUtil.sentMessage("23988", "Response Data: " + e, "国创资源库");
            throw new MeException(e.getMessage());
        }
    }
    /**
     * 封装文件漏下，补充
     *
     * @throws MeException
     */
    @Override
    public void downloadFile() throws MeException {
//        查询文件id
//        List<ComponentModelSb> list = componentModelSbService.list();
//        for (ComponentModelSb componentModelSb : list) {
//            log.info("===="+componentModelSb.getStandardSymbolName());
//            if (Objects.nonNull(componentModelSb.getPadsSymbol())){
//                getFile(componentModelSb.getPadsSymbol().toString(),BizCode.SYMBOLS.getType());
//            }
//            if (Objects.nonNull(componentModelSb.getCadenceSymbol())){
//                getFile(componentModelSb.getCadenceSymbol().toString(),BizCode.SYMBOLS.getType());
//            }
//            if (Objects.nonNull(componentModelSb.getAltiumSymbol())){
//                getFile(componentModelSb.getAltiumSymbol().toString(),BizCode.SYMBOLS.getType());
//            }
//        }

        List<ComponentModelFP> componentModelFPS = componentModelFPService.list();
        int i = 0;
        for (ComponentModelFP componentModelFP : componentModelFPS) {
            i++;
            log.info(i + "====" + componentModelFP.getStandardFootprintName());
            if (Objects.nonNull(componentModelFP.getPadsFootprint())) {
                getFile(componentModelFP.getPadsFootprint().toString(), BizCode.FOOT_PRINT.getType());
            }
            if (Objects.nonNull(componentModelFP.getCadenceFootprint())) {
                getFile(componentModelFP.getCadenceFootprint().toString(), BizCode.FOOT_PRINT.getType());
            }
            if (Objects.nonNull(componentModelFP.getAltiumFootprint())) {
                getFile(componentModelFP.getAltiumFootprint().toString(), BizCode.FOOT_PRINT.getType());
            }
        }

    }

    @Override
    public void getFactoryInfo() throws MeException {
        // 厂商
        String url = gcUrl + "/resource/openapi/v1/component/organization/get";
        try {
            // 添加自定义头部参数
            String authorizationToken = GCutil.getToken();
            Map<String, String> headers = new HashMap<>();
            headers.put("client-id", clientId);
            headers.put("Authorization", authorizationToken);

            HttpResponse response = HttpUtil.createGet(url)
                    //                .form(paramMap)
                    .addHeaders(headers)
                    .setConnectionTimeout(connectionTimeout)
                    .execute();
            if (!Objects.equals(response.getStatus(), HttpStatus.HTTP_OK)) {
                throw new MeException("请求异常：" + response.body());
            }
            JSONObject jsonObject = JSONObject.parseObject(response.body());
            JSONArray dataArray = jsonObject.getJSONArray("data");
            // 将 JSON 数组转换为 List<OrganizationCreateReqDTO>
            List<OrganizationCreateReqDTO> organizationList = JSONArray.parseArray(dataArray.toJSONString(), OrganizationCreateReqDTO.class);
            // 获取组织（厂商）信息接口后保存
            CommonResult<Boolean> result = organizationApi.createOrUpdate(organizationList);
            if (result == null || !result.getCheckedData()) {
                log.info("保存组织信息失败");
                throw new MeException("保存组织信息失败");
            } else {
                log.info("save organization {}", organizationList.size());
            }


            // 解析分类数据，然后通过rpc接口保存
            //  分类信息保存
            for (OrganizationCreateReqDTO org : organizationList) {
                // 同步厂商logo图片
                if (org.getOrganizationLogo() != null && org.getOrganizationLogo() > 0) {
                    getFile(String.valueOf(org.getOrganizationLogo()), BizCode.IMAGE.getType());
                }

                // 同步厂商分类
                String categoryUrl = gcUrl + "/resource/openapi/v1/component/classification/get?orgId=" + org.getId();
                HttpResponse categoryResponse = HttpUtil.createGet(categoryUrl)
                        .addHeaders(headers)
                        .setConnectionTimeout(connectionTimeout)
                        .execute();
                if (!Objects.equals(categoryResponse.getStatus(), HttpStatus.HTTP_OK)) {
                    throw new MeException("分类请求异常：" + categoryResponse.body());
                }
                JSONArray categoryDataArray = JSONObject.parseObject(categoryResponse.body()).getJSONArray("data");
                List<CategoryCreateReqVO> createReqList = JSONArray.parseArray(categoryDataArray.toJSONString(), CategoryCreateReqVO.class);
                // 1 零部件，2元器件
                createReqList.forEach(categoryCreateReqVO -> {
                    categoryCreateReqVO.setType(2);
                    categoryCreateReqVO.setOrgId(org.getId());
                });
                result = categoryControllerApi.createOrUpdate(createReqList);
                if (result == null || !result.getCheckedData()) {
                    log.info("保存分类信息失败{}", org.getId());
                    throw new MeException("保存分类信息失败");
                } else {
                    log.info("save success {},{} category", org.getId(), createReqList.size());
                }

            }
        } catch (MeException e) {
            throw new MeException(e.getMessage());
        }

    }

    @Override
//    @Transactional
    public boolean scheduleUpdate(List<CallbackNotification> list) throws MeException {
        if (CollectionUtil.isEmpty(list)){
            //查询需要更新的数据
            LambdaQueryWrapper<CallbackNotification> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.ne(CallbackNotification::getSynStatus, 1);
//            queryWrapper.eq(CallbackNotification::getSynStatus, 2);
            list = callbackNotificationDao.selectList(queryWrapper);
        }
        for (CallbackNotification callbackNotification : list) {
            try {
                if (CollectionUtil.isEmpty(list)) {
                    XxlJobHelper.log(LocalDateTime.now() + "--> 没有可更新数据");
                    return true;
                }

                // 将 resourceId 字段拼接成字符串
//                String concatenatedIds = list.stream()
//                        .map(notification -> String.valueOf(notification.getResourceId()))
//                        .collect(Collectors.joining(","));

                //拉取数据更新
                this.batchGet(callbackNotification.getResourceId().toString(),callbackNotification.getCreateBy());
//                this.batchGet(callbackNotification.getResourceId().toString(),"KOM");

                //回写状态
                callbackNotification.setSynErr(null);
                callbackNotification.setSynStatus(1);
                callbackNotification.setSynTime(LocalDateTime.now());

                XxlJobHelper.log(LocalDateTime.now() + "--> 数据更新成功");
//                return true;
            } catch (MeException e) {
                XxlJobHelper.log("异常：" + e.getMessage());
                log.info("异常：{}", e.getMessage());
                callbackNotification.setSynTime(LocalDateTime.now());
                callbackNotification.setSynStatus(2);
                callbackNotification.setSynErr(e.getMessage());
                //回滚当前事务
//                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

                //抛出异常，用于影响控制流程
//                throw new MeException(e.getMessage());
            } finally {
                try {
                    // 开启新事务
                    DefaultTransactionDefinition def = new DefaultTransactionDefinition();
                    def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
                    TransactionStatus transaction = dstManager.getTransaction(def);

                    // 进行数据更新操作
                    boolean b = this.updateById(callbackNotification);

                    // 提交新事务
                    dstManager.commit(transaction);
                } catch (Exception e) {
                    // 处理提交新事务失败的情况
                    log.error("Failed to commit new transaction in finally block: {}", e.getMessage());
                }
            }
        }
        return true;
    }

    @Override
    public boolean modelApplication(ModelApplication modelApplication) throws MeException {

        //先判断是否已经发过申请
        LambdaQueryWrapper<ModelApplication> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ModelApplication::getPartNumber, modelApplication.getPartNumber());
        List<ModelApplication> modelApplications = modelApplicationDao.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(modelApplications)) {
            throw new MeException("此型号已申请建模：" + modelApplication.getPartNumber());
        }

        //发送到国创
        String url = gcUrl + "/resource/openapi/v1/component/request/create";
        // 添加自定义头部参数
        try {
            String authorizationToken = GCutil.getToken();
            Map<String, String> headers = new HashMap<>();
            headers.put("client-id", clientId);
            headers.put("Authorization", authorizationToken);
            Map<String, Object> paramMap = new HashMap<>();

            paramMap.put("partNumber", modelApplication.getPartNumber());
            paramMap.put("orgName", modelApplication.getOrgName());
            paramMap.put("datasheet", modelApplication.getDatasheet());
            if (!StringUtil.isEmpty(modelApplication.getRemark())) {
                paramMap.put("remark", modelApplication.getRemark());
            }
            HttpResponse response = HttpRequest.post(url)
                    .body(JSONUtil.toJsonStr(paramMap))  // 设置请求体
                    .addHeaders(headers)  // 设置请求头，表示发送的是JSON数据
                    .execute();  // 执行请求

            if (!Objects.equals(response.getStatus(), HttpStatus.HTTP_OK)) {
                throw new MeException("请求异常：" + response.body());
            }
            JSONObject jsonObject = JSONObject.parseObject(response.body());

            Boolean dataValue = jsonObject.getBoolean("data"); // 提取data字段的值

            if (Objects.nonNull(dataValue) && dataValue) {
                modelApplication.setIsSuccessful("true");
            }
            return true;
        } catch (Exception e) {
            modelApplication.setIsSuccessful(e.getMessage());
            throw new MeException(e.getMessage());
        } finally {
            //本地记录
            modelApplication.setCreateTime(LocalDateTime.now());
            modelApplicationDao.insert(modelApplication);
        }

    }

    public static void main(String[] args) {
        // Excel 文件路径
        String excelFilePath = "D:\\Users\\23988\\My Document\\WXWork\\1688857311497771\\Cache\\File\\2024-09\\金百泽本地数据清洗.xlsx";
        // 文本文件路径
        String textFilePath = "D:\\test\\test\\textfile.txt";
        // 需要提取的列索引（假设从 0 开始，第一列的索引为 0）
        int columnIndex = 8; // 修改为你要提取的列索引

        // 读取 Excel 文件
        File file = new File(excelFilePath);
        ExcelReader reader = ExcelUtil.getReader(file);

        // 读取所有数据（或指定的工作表）
        List<List<Object>> rows = reader.read();

        // 提取指定列的内容
        List<String> columnData = rows.stream()
                .skip(1) // 如果文件有标题行，可以跳过
                .map(row -> row.get(columnIndex))
                .filter(obj -> obj != null) // 过滤掉 null 值
                .map(Object::toString) // 转换为字符串
                .collect(Collectors.toList());

        // 写入到文本文件
        FileUtil.writeLines(columnData, textFilePath, "UTF-8");

        System.out.println("数据已成功写入到 " + textFilePath);
    }
}
